﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using SPListsCaller.Data;
using EspaceCo.Console.SPWebServices;
using System.Xml;
using System.IO;
using Microsoft.Win32;
using System.Xml.Serialization;
using SPListsCaller.Tools;
using System.Data;
using System.Web.Services.Protocols;
using SPListsCaller.WS;
using ICSharpCode.AvalonEdit.Folding;
using ElkiTools.SPListCaller.Core.Extensions;
using System.Xml.Linq;

namespace SPListsCaller
{
    /// <summary>
    /// Logique d'interaction pour MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public GetListItemsModel Model { get; set; }

        public KeyValuePair<string, string> CurrentEditedProperty { get; set; }

        public FoldingManager FoldingManager { get; set; }

        private string _currentXmlFilePath;

        public MainWindow()
        {
            InitializeComponent();

            InitializeData();

            InitializePopup();
        }

        private void InitializePopup()
        {
            XmlFoldingStrategy foldingStrategy = new XmlFoldingStrategy();

            this.paramEditor.TextArea.IndentationStrategy = new ICSharpCode.AvalonEdit.Indentation.DefaultIndentationStrategy();
            if (FoldingManager == null) FoldingManager = FoldingManager.Install(paramEditor.TextArea);
            foldingStrategy.UpdateFoldings(FoldingManager, paramEditor.Document);

        }

        private void InitializeData()
        {
            this.Model = new GetListItemsModel();
            this.DataContext = this.Model;
        }

        private void CallByQuery_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                XmlNode result = ListsWS.GetListItems_ByQuery(Model.Url, Model.QueryParams, Model.Credential, null);
                SaveAndDisplayResult(result);
            }
            catch (SoapException excSoap)
            {
                MessageBox.Show("Echec d'appel : " + excSoap.Detail.InnerText);
            }
            catch (Exception exc)
            {
                MessageBox.Show("Echec d'appel : " + exc.Message);
            }
        }

        private void SaveAndDisplayResult(XmlNode result)
        {
            if (result != null)
            {
                XmlDocument xDoc = null;
                try
                {
                    // Enregistrement du flux XML dans un fichier temporaire
                    _currentXmlFilePath = System.IO.Path.GetTempFileName();
                    xDoc = new XmlDocument();
                    XmlNode xRoot = xDoc.ImportNode(result, true);
                    xDoc.AppendChild(xRoot);
                    xDoc.Save(_currentXmlFilePath);
                }
                catch (Exception exc)
                {
                    MessageBox.Show("Echec d'enregistrement du flux : " + exc.Message);
                }

                if (xDoc != null)
                {
                    try
                    {
                        // Alimentation de la grille
                        this.Model.CurrentDataTable = ZRowTools.GetFullDataTable(xDoc.OuterXml);
                        dgResult.ItemsSource = this.Model.CurrentDataTable.AsDataView();

                        // Alimentation de la zone de texte
                        this.textEditor.Load(_currentXmlFilePath);
                    }
                    catch (Exception excDisplay)
                    {
                        MessageBox.Show("Echec d'affichage : " + excDisplay.Message);
                    }
                }
            }
        }

        private void SaveXml_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (!string.IsNullOrEmpty(this._currentXmlFilePath))
                {
                    SaveFileDialog dlg = new SaveFileDialog();
                    if (dlg.ShowDialog() == true)
                    {
                        File.Copy(this._currentXmlFilePath, dlg.FileName);
                    }
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show("Echec d'enregistrement : " + exc.Message);
            }
        }

        private void SaveConfig_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                SaveFileDialog dlg = new SaveFileDialog();
                if (dlg.ShowDialog() == true)
                {
                    this.Model.SaveAs(dlg.FileName);
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show("Echec d'enregistrement : " + exc.Message);
            }
        }

        private void LoadConfig_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                OpenFileDialog dlg = new OpenFileDialog();
                if (dlg.ShowDialog() == true)
                {
                    this.Model.LoadFrom(dlg.FileName);
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show("Echec de chargement : " + exc.Message);
            }
        }

        private void ExportQuery_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                SaveFileDialog dlg = new SaveFileDialog();
                if (dlg.ShowDialog() == true)
                {
                    this.Model.QueryParams.Export(dlg.FileName);
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show("Echec d'enregistrement : " + exc.Message);
            }
        }

        private void ImportQuery_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                OpenFileDialog dlg = new OpenFileDialog();
                if (dlg.ShowDialog() == true)
                {
                    this.Model.QueryParams = GetListItems_CallParameters.LoadFrom(dlg.FileName);

                    //Refresh UI
                    //TODO : trouver une solution plus propre
                    this.DataContext = null;
                    this.DataContext = this.Model;
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show("Echec de chargement : " + exc.Message);
            }
        }


        //------------------------------------------------------------------------------------------------------------
        #region Popup
        //------------------------------------------------------------------------------------------------------------

        private void OnEditXmlProperty(object sender, RoutedEventArgs e)
        {
            // Tag du bouton d'appel
            string senderTag = ((FrameworkElement)sender).Tag.ToString();

            // Valeur de la propriété associée
            BeginEditProperty(senderTag);
            this.paramEditor.Text = this.CurrentEditedProperty.Value;

            // Ouverture de la popup
            this.paramEditorWindow.WindowState = Xceed.Wpf.Toolkit.WindowState.Open;
        }

        private void OnValidatePopup(object sender, RoutedEventArgs e)
        {
            // Masquage de la popup
            this.paramEditorWindow.WindowState = Xceed.Wpf.Toolkit.WindowState.Closed;

            // Validation de la saisie
            EndEditProperty();
        }

        private void OnCancelPopup(object sender, RoutedEventArgs e)
        {
            // Masquage de la popup
            this.paramEditorWindow.WindowState = Xceed.Wpf.Toolkit.WindowState.Closed;
        }

        private void BeginEditProperty(string propertyName)
        {
            // Récupération de la propriété du modèle à partir de son nom ET indentation
            string sBuffer = this.Model.QueryParams.GetType()
                    .GetProperty(propertyName)
                    .GetValue(this.Model.QueryParams, null)
                    .ToString();

            // Conservation de cette valeur
            this.CurrentEditedProperty = new KeyValuePair<string, string>
            (
                propertyName,
                XElementExt.GetIndentedXml(sBuffer)
            );
        }

        private void EndEditProperty()
        {
            // Applatissement de la chaine
            string sBuffer = XElementExt.GetFlatXml(this.paramEditor.Text);

            // Affectation à la propriété du modèle
            this.Model.QueryParams
                .GetType()
                .GetProperty(this.CurrentEditedProperty.Key)
                .SetValue(this.Model.QueryParams, sBuffer, null);
        }
        //------------------------------------------------------------------------------------------------------------
        #endregion Popup
        //------------------------------------------------------------------------------------------------------------
    }
}
